#include "fishbot_behavior_tree/async_behavior_base.hpp"

namespace fishbot
{
    namespace behavior_tree
    {
        AsyncBehaviorBase::AsyncBehaviorBase(const std::string &name,
                                             const BT::NodeConfiguration &config,
                                             const std::shared_ptr<BehaviorContext> &shared_resources)
            : SharedResourcesNode<BT::StatefulActionNode>(name, config, shared_resources)
        {
        }

        AsyncBehaviorBase::~AsyncBehaviorBase() = default;
        /**
         * @brief 在行为树节点开始执行时调用，
         *        使用 std::async 启动异步任务，调用 runAsync 函数，
         *        将异步任务的结果包装为 std::shared_future，以便后续检查任务状态
         * 
         * @return BT::NodeStatus 
         */
        BT::NodeStatus AsyncBehaviorBase::onStart()
        {
            // 启动异步处理
            execute_action_future_ = std::shared_future<tl::expected<bool, std::string>>(std::async(std::launch::async, &AsyncBehaviorBase::runAsync, this).share());
            RCLCPP_INFO_STREAM(this->shared_resources_->node_->get_logger(), this->name() << ": start");
            RCLCPP_INFO_STREAM(this->shared_resources_->node_->get_logger(), this->name() << ": running");
            // 返回状态为运行中
            return BT::NodeStatus::RUNNING;
        }
        /**
         * @brief 在节点处于运行状态时调用，用于检查异步任务的状态
         *        检查 execute_action_future_ 是否有效，并判断任务是否已完成
         *        如果任务完成，获取结果并根据结果返回相应的状态
         *        如果任务未完成，继续返回 BT::NodeStatus::RUNNING
         * @return BT::NodeStatus 
         */
        BT::NodeStatus AsyncBehaviorBase::onRunning()
        {
            // 检查异步处理状态
            if (execute_action_future_.valid() && execute_action_future_.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
            {
                // 异步处理已完成
                try
                {
                    auto result = execute_action_future_.get();
                    if (result)
                    {
                        bool success = result.value();
                        if (success)
                        {
                            RCLCPP_INFO_STREAM(this->shared_resources_->node_->get_logger(), this->name() << ": success");
                            return BT::NodeStatus::SUCCESS;
                        }
                        else
                        {
                            RCLCPP_INFO_STREAM(this->shared_resources_->node_->get_logger(), this->name() << ": failure");
                            return BT::NodeStatus::FAILURE;
                        }
                    }
                    else
                    {
                        RCLCPP_ERROR_STREAM(this->shared_resources_->node_->get_logger(), this->name() << "Async task failed with error: " << result.error());
                        return BT::NodeStatus::FAILURE;
                    }
                }
                catch (const std::exception &e)
                {
                    RCLCPP_ERROR_STREAM(this->shared_resources_->node_->get_logger(), this->name() << "Exception during async behavior execution: " << e.what());
                    return BT::NodeStatus::FAILURE;
                }
            }
            return BT::NodeStatus::RUNNING;
        }
        /**
         * @brief 在节点被中止时调用，用于清理异步任务
         *        如果异步任务有效，等待任务完成并重置 execute_action_future_
         *        确保异步任务的结果被正确处理，避免资源泄漏
         */
        void AsyncBehaviorBase::onHalted()
        {
            // 尝试取消异步处理
            if (execute_action_future_.valid())
            {
                execute_action_future_.wait();
                execute_action_future_ = std::shared_future<tl::expected<bool, std::string>>();
            }
        }
        /**
         * @brief 调用纯虚函数 doWork，执行具体的任务逻辑，并返回任务的结果
         *        捕获任务执行中的异常，并将异常信息封装为 tl::expected 的错误值
         * 
         * @return tl::expected<bool, std::string> 
         */
        tl::expected<bool, std::string> AsyncBehaviorBase::runAsync()
        {
            try
            {
                // 执行异步处理
                auto result = doWork();
                // execute_action_promise_.set_value(result);
                if (!result)
                {
                    // throw std::runtime_error("Async task returned unexpected value: " + );
                    return tl::make_unexpected(this->name() + ": runAsync: " + result.error());
                }
                else
                {
                    return true;
                }
            }
            catch (const std::exception &e)
            {
                // 异常处理
                // execute_action_promise_.set_exception(std::make_exception_ptr(e));
                return tl::make_unexpected(this->name() + ": runAsync: " + e.what());
            }
        }
    }
}